import 'package:flutter/cupertino.dart';
import 'package:petitparser/debug.dart';
import 'package:petitparser/petitparser.dart';

import '../common/test_page.dart';

final identifier = letter() & word().star();
final labeledIdentifier = letter().labeled('first') & word().star().labeled('remaining');

bool isProfileFrame(ProfileFrame frame, {required String parser, int count = 0}) {
  bool isParserValid = frame.parser.toString().contains(parser);
  bool isCountValid = frame.count == count;
  bool isElapsedValid = frame.elapsed.compareTo(Duration.zero) >= 0;
  bool isToStringValid = frame.toString().startsWith(count.toString()) && frame.toString().contains(parser);

  return isParserValid && isCountValid && isElapsedValid && isToStringValid;
}

class DebugTestPage extends TestPage {
  DebugTestPage(String title, {Key? key}) : super(title, key: key) {
    group('profile', () {
      test('success', () {
        final frames = <ProfileFrame>[];
        final parser = profile(identifier, output: frames.add);
        expect(parser.parse('ab123').isSuccess, null);
        expect(frames, null);
      });
      test('labeled', () {
        final frames = <ProfileFrame>[];
        final parser = profile(labeledIdentifier, output: frames.add, predicate: (parser) => parser is LabeledParser);
        expect(parser.parse('ab123').isSuccess, null);
        expect(frames, null);
      });
      test('failure', () {
        final frames = <ProfileFrame>[];
        final parser = profile(identifier, output: frames.add);
        expect(parser.parse('1').isFailure, null);
        expect(frames, null);
      });
    });
    group('progress', () {
      test('success', () {
        final frames = <ProgressFrame>[];
        final parser = progress(identifier, output: frames.add);
        expect(parser.parse('ab123').isSuccess, null);
        expect(frames, null);
      });
      test('labeled', () {
        final frames = <ProgressFrame>[];
        final parser = progress(labeledIdentifier, output: frames.add, predicate: (parser) => parser is LabeledParser);
        expect(parser.parse('ab123').isSuccess, null);
        expect(frames, null);
      });
      test('failure', () {
        final frames = <ProgressFrame>[];
        final parser = progress(identifier, output: frames.add);
        expect(parser.parse('1').isFailure, null);
        expect(frames, null);
      });
    });
    group('trace', () {
      test('success', () {
        final events = <TraceEvent>[];
        final parser = trace(identifier, output: events.add);
        expect(parser.parse('a').isSuccess, null);
        expect(events, null);
      });
      test('labeled', () {
        final events = <TraceEvent>[];
        final parser = trace(labeledIdentifier, output: events.add, predicate: (parser) => parser is LabeledParser);
        expect(parser.parse('ab123').isSuccess, null);
        expect(events, null);
      });
      test('failure', () {
        final events = <TraceEvent>[];
        final parser = trace(identifier, output: events.add);
        expect(parser.parse('1').isFailure, null);
        expect(events, null);
      });
    });
  }
}
